package lexer

import (
	

	
)

func absLocPathState( *Lexer) stateFn {
	.emit(XItemAbsLocPath)
	return stepState
}

func abbrAbsLocPathState( *Lexer) stateFn {
	.emit(XItemAbbrAbsLocPath)
	return stepState
}

func relLocPathState( *Lexer) stateFn {
	.emit(XItemRelLocPath)
	return stepState
}

func abbrRelLocPathState( *Lexer) stateFn {
	.emit(XItemAbbrRelLocPath)
	return stepState
}

func stepState( *Lexer) stateFn {
	.skipWS(true)
	 := .next()

	for isElemChar() {
		 = .next()
	}

	.backup()
	 := .input[.start:.pos]

	,  := parseSeparators(, )
	if  != nil {
		return .errorf(.Error())
	}

	return getNextPathState(, )
}

func parseSeparators( *Lexer,  string) (XItemType, error) {
	.skipWS(false)
	 := XItemType(XItemQName)
	 := .peek()

	if string() == ":" && string(.peekAt(2)) == ":" {
		var  error
		if ,  = getAxis(, );  != nil {
			return , fmt.Errorf(.Error())
		}
	} else if string() == ":" {
		 = XItemNCName
		.emitVal(, )
		.skip(1)
		.skipWS(true)
	} else if string() == "@" {
		 = XItemAbbrAxis
		.emitVal(, )
		.skip(1)
		.skipWS(true)
	} else if string() == "(" {
		var  error
		if ,  = getNT(, );  != nil {
			return , fmt.Errorf(.Error())
		}
	} else if len() > 0 {
		.emitVal(, )
	}

	return , nil
}

func getAxis( *Lexer,  string) (XItemType, error) {
	var  XItemType
	for  := range xconst.AxisNames {
		if  == xconst.AxisNames[] {
			 = XItemAxis
		}
	}
	if  != XItemAxis {
		return , fmt.Errorf("Invalid Axis specifier, %s", )
	}
	.emitVal(, )
	.skip(2)
	.skipWS(true)
	return , nil
}

func getNT( *Lexer,  string) (XItemType, error) {
	 := false
	for ,  := range xconst.NodeTypes {
		if  ==  {
			 = true
			break
		}
	}

	if  {
		return procNT(, )
	}

	return XItemError, fmt.Errorf("Invalid node-type " + )
}

func procNT( *Lexer,  string) (XItemType, error) {
	 := XItemType(XItemNodeType)
	.emitVal(, )
	.skip(1)
	.skipWS(true)
	 := .peek()
	if  == xconst.NodeTypeProcInst && (string() == `"` || string() == `'`) {
		if  := getStrLit(, XItemProcLit);  != nil {
			return , fmt.Errorf(.Error())
		}
		.skipWS(true)
		 = .next()
	}

	if string() != ")" {
		return , fmt.Errorf("Missing ) at end of NodeType declaration.")
	}

	.skip(1)
	return , nil
}

func procFunc( *Lexer,  string) error {
	 := XItemType(XItemFunction)
	.emitVal(, )
	.skip(1)
	.skipWS(true)
	if string(.peek()) != ")" {
		.emit(XItemArgument)
		for {
			for  := startState;  != nil; {
				 = ()
			}
			.skipWS(true)

			if string(.peek()) == "," {
				.emit(XItemArgument)
				.skip(1)
			} else if string(.peek()) == ")" {
				.emit(XItemEndFunction)
				.skip(1)
				break
			} else if .peek() == eof {
				return fmt.Errorf("Missing ) at end of function declaration.")
			}
		}
	} else {
		.emit(XItemEndFunction)
		.skip(1)
	}

	return nil
}

func getNextPathState( *Lexer,  XItemType) stateFn {
	 :=  == XItemAxis ||  == XItemAbbrAxis ||  == XItemNCName

	.skipWS(true)

	for string(.peek()) == "[" {
		if  := getPred();  != nil {
			return .errorf(.Error())
		}
	}

	if string(.peek()) == "/" && ! {
		.skip(1)
		if string(.peek()) == "/" {
			.skip(1)
			return abbrRelLocPathState
		}
		.skipWS(true)
		return relLocPathState
	} else if  && isElemChar(.peek()) {
		return stepState
	}

	if  {
		return .errorf("Step is not complete")
	}

	.emit(XItemEndPath)
	return findOperatorState
}

func getPred( *Lexer) error {
	.emit(XItemPredicate)
	.skip(1)
	.skipWS(true)

	if string(.peek()) == "]" {
		return fmt.Errorf("Missing content in predicate.")
	}

	for  := startState;  != nil; {
		 = ()
	}

	.skipWS(true)
	if string(.peek()) != "]" {
		return fmt.Errorf("Missing ] at end of predicate.")
	}
	.skip(1)
	.emit(XItemEndPredicate)
	.skipWS(true)

	return nil
}